import { post } from '@/utils/http/Axios';
import { formatCondition } from "../componentRequest/formatCondition.js";
import { requestMap } from "../componentRequest/componentRequestConfig.js";
import { $each, $isEmptyObject, deepClone } from "../index";
/**
 * 动态数据生成参数，这部分抽离出来，是为了编辑态和运行态通用
 * @param {string} componentId - 组件id
 * @param {Object} options - 其他参数
 * @returns {Object}
 */
export async function generateFetchParams(
  componentId,
  options,
){
  const { relationData, relationOptionIndex, componentKey, pageGlobalParameters, externalParams } = deepClone(options);
  // 根据配置信息转换为请求参数
  const { resetRelationMap, format, resetJumpFilters, resetGlobalParameterFilters, resetDrillList, resetDrillBreadcrumbs, resetLinkageList } = formatCondition();

  // 获取当前的数据源配置信息
  const { dcConfig, fields } = relationData;

  // 组件还未绑定数据集,直接return
  if (!dcConfig.filters.tableId) {
    return;
  }

  // 使用新的relationMap
  resetRelationMap(fields);
  // 重置下钻
  resetDrillList(options?.drillList);
  // 重置面包屑
  resetDrillBreadcrumbs(options?.drillBreadcrumbs);
  // 重置联动
  resetLinkageList(options?.linkageList);
  // 重置跳转过滤字段信息及过滤值
  // 判断是低代码嵌入的
  const micAppData = window.eventCenterForViteApp?.getData();
  let micAppUrl = null;
  if (micAppData && micAppData.type === 'asa') {
    micAppUrl = micAppData.url;
  }
  // 判断外部参数，如被iframe嵌套
  if (externalParams && externalParams.url) {
    micAppUrl = externalParams.url;
  }
  const urlParameterMap = $urlParse(micAppUrl);
  // 跳转过滤值
  const jumpFilterList = await getJumpFilterForComponent(dcConfig, urlParameterMap);
  resetJumpFilters(jumpFilterList);
  // 重置全局参数字段信息及过滤值
  resetGlobalParameterFilters(getComponentGlobalParameterFilters(componentId, urlParameterMap, pageGlobalParameters));
  // 获取组件类型对应不同的format
  const componentType = checkComponentFormatType(componentKey);
  // 根据组件类型调用不同的接口
  const { requestFormat: requestFormatMethod, api } =
    requestMap[componentType];
  // 获取数据源对应的信息
  const { catalogId, tableId, tableName, tableBizCode, interval, realIntervalValue, intervalType, monitorType, pageSize, beginDate, endDate } = dcConfig.filters;
  // 获取请求参数
  const { requestParams, responseRelations } = format[requestFormatMethod]({
    relationOptionIndex,
    chartType: componentKey,
    ...options,
  });
  // 根据后端要求，地图类型需要增加dashboardType字段，地图为MAP，其他为OTHER
  const isMap = componentKey.includes('map');
  // 根据后端要求，iot类型需要增加interval字段
  const isIot = componentKey.includes('iot');
  const isIotLine = componentKey === 'iot_basic_line';
  // 混入参数
  let otherParams = {};
  if (isIot) {
    otherParams = {
      interval: isIot ? interval : null,
      monitorType: isIotLine ? monitorType : null,
      pageSize: isIotLine && monitorType === 'REAL' ? pageSize : null,
      realIntervalValue: isIotLine && monitorType === 'REAL' ? realIntervalValue : null,
      intervalType: isIotLine && monitorType === 'REAL' ? intervalType : null,
      beginDate: isIotLine && monitorType === 'HISTORY' ? beginDate : null,
      endDate: isIotLine && monitorType === 'HISTORY' ? endDate : null,
    }
  }
  const params = Object.assign(requestParams, {
    fullData: !!options.released, // 发布状态
    dataAccessType: dcConfig.type,
    catalogId,
    tableId,
    tableName,
    componentId,
    businessCode: catalogId,
    originTableBizCode: tableId,
    dashboardType: isMap ? 'MAP' : 'OTHER',
    // 低代码下分析应用需加上标识
    schema: document.domain.startsWith('asa') ? 'low_code_application' : '',
  }, otherParams);
  //应用资源中心不需要传tableBizCode
  if (dcConfig.type !== 'APPLICATION_RESOURCES') {
    params['tableBizCode'] = tableBizCode;
  }
  return {
    params,
    responseRelations,
    api: api(dcConfig.type),
  };
}

/**
* 判断组件属于那种类型，返回对应的format和接口信息
* @param {string} componentName 组件名字
* @returns {string}
*/
function checkComponentFormatType(componentName) {
  if (componentName === 'control_textFilter') {
    return 'TextFilter';
  }
  if (componentName === 'table_common') {
    return 'CommonTable';
  }
  if (componentName === 'iot_basic_line') {
    return 'IotLineEcharts';
  }
  if (/^iot_/.test(componentName) && componentName !== 'iot_basic_line') {
    return 'IotEcharts';
  }
  return 'Echarts';
}
/**
*  获取Url参数
 *  @param micAppUrl 因为被微前端嵌了之后，获取不到url，需要这里提供一个参数
*/
export function $urlParse(micAppUrl) {
  // 判断是否是预览页面，预览页面采用iframe，发布页面不是
  let isPreview = false;
  // 因为大屏可能会被套iframe的形式，这时候不同域会报错，但是预览又必须使用这种形式，所以这里做了try catch
  try {
    isPreview = window.parent.location.pathname && window.parent.location.pathname.includes('preview');
  } catch (err) {
    isPreview = false;
  }
  let url = null;
  if(micAppUrl) {
    url = micAppUrl;
  } else {
    url = isPreview ? (window.parent.location.search || window.parent.location.hash) : (window.location.search || window.location.hash);
  }
  const _obj = {};
  const reg = /[?&][^?&]+=[^?&]+/g; // 匹配 ?或者&  +  非?或者&一个或多个 +  =  +  非?或者&一个或多个 + 全局
  const arr = url.match(reg); // 切割为两个数组  ['?id=12345', '&a=b']
  if (arr) {
    arr.forEach((item) => {
      const tempArr = item.substring(1).split('=');
      const value = decodeURIComponent(tempArr[1]);
      const result = value.startsWith('[') ? JSON.parse(value) : value;
      _obj[decodeURIComponent(tempArr[0])] = result;
    });
  }
  return _obj;
}

// 这里封装一个函数去对外暴露是不是低代码过来的,主要用来判断，过滤条件的类型，如：包含OR属于
export function formSmartToScreen(type) {
  // 判断是低代码嵌入的
  const micAppData = window.eventCenterForViteApp?.getData();
  let micAppUrl = null;
  if (micAppData && micAppData.type === 'asa') {
    micAppUrl = micAppData.url;
  }
  const urlParameterMap = $urlParse(micAppUrl);
  if (type instanceof Array) {
    const arr = {};
    $each(type || [], (typeItem) => {
      if (urlParameterMap.hasOwnProperty(typeItem)) {
        arr[typeItem] = urlParameterMap[typeItem];
      }
    })
    return arr;
  }
  // 除了要返回的数组和string外，其他的情况全部返回
  return urlParameterMap;
}

async function getJumpFilterForComponent(dcConfig, urlParameterMap) {
  /** filter参数的数据结构
   * const filter = {
   *  '2000123': { // 数据集ID
   *    'DS_COL6': { // 对应的字段
   *       filterValue: '小王', // 过滤的值
   *       filterDateFormat: '' // 针对日期类型的特殊处理
   *     }
   *   }
   * }
   */
  const { filter } = urlParameterMap;
  // 获取绑定数据源信息
  const { catalogId, tableId, tableName, tableBizCode } = dcConfig.filters;
  if (!filter) {
    return [];
  }
  const filterObject = JSON.parse(filter);
  if (!filterObject[tableId]) {
    return [];
  }
  const jumpFilterFieldMap = filterObject[tableId];
  const jumpFilterList = [];
  // 获取字段列表
  let params = { dataAccessType: dcConfig.type, catalogId, tableId, tableName, tableBizCode };
  let url = '/data-analysis/api/v3/dashboard/catalog/table/column'
  if (dcConfig.type === 'APPLICATION_RESOURCES') {
    params = {
      businessCode: catalogId,
      originTableBizCode: tableId,
    };
    url = '/visualization-data/api/v1/data-center/business/table/column';
  }
  const coloumnRes = await post(url, params)
  const { dimensionFieldList , dimensionColumnList } = coloumnRes.data || {};
  const dimensionField = formatColumnList(dimensionFieldList || dimensionColumnList || []);
  if(!dimensionField.find(item => jumpFilterFieldMap.hasOwnProperty(item.datasetFieldName))){
    return [];
  }
  dimensionField.forEach(item => {
    if(jumpFilterFieldMap.hasOwnProperty(item.datasetFieldName)){
      const { filterValue, filterDateFormat } = jumpFilterFieldMap[item.datasetFieldName];
      item.filterDateFormat = filterDateFormat;
      jumpFilterList.push({ field: item, filterValue });
    }
  });
  return jumpFilterList;
}
//处理字段格式
function formatColumnList(columnList) {
  columnList.forEach(item=>{
    item.catalogTableColumnType = item.catalogTableColumnType || item.columnType;
    item.datasetFieldName = item.datasetFieldName || item.columnName;
  })
  return columnList;
}
/**
 * 获取当前组件配置的全局参数过滤信息
 * @param {*} componentId 组件id
 * @param {*} urlParameterMap 地址栏信息
 * @param {*} pageGlobalParameters 全局参数信息
 * @param {*} externalDealData 外部处理函数
 * @returns
 */
function getComponentGlobalParameterFilters(componentId, urlParameterMap, pageGlobalParameters = []) {
  const componentGlobalParameterFilters = [];
  pageGlobalParameters.forEach((parameter) => {
    const { name, checkedComponentMap } = parameter;
    if (urlParameterMap.hasOwnProperty(name) && !$isEmptyObject(checkedComponentMap[componentId])) {
      let filterValue = urlParameterMap[name];
      if (checkedComponentMap[componentId]?.externalDealData) {
        const data = JSON.parse(JSON.stringify(filterValue));
        filterValue = checkedComponentMap[componentId].externalDealData(data);
      }
      componentGlobalParameterFilters.push({
        filterValue,
        field: checkedComponentMap[componentId],
      });
    }
  });
  return componentGlobalParameterFilters;
}
